import Sortable from '@timluo465/react-sortablejs';
import classNames from 'classnames';
import { WeaLocaleProvider } from "ecCom";
import { toJS } from 'mobx';
import React, { Fragment } from 'react';
import { dragDelayTime, DragKey } from '../../../../../constants/form';
import utils from '../../../../../utils';
import Droppable from '../../../../common/droppable';
import BaseDesign from '../base/Design';
import ActionGroup from './ActionGroup';
import defaultData from './data';
import './index.less';
const { getLabel } = WeaLocaleProvider;

const MINH = 80;
const sortableOpts = {
  group: {
    name: DragKey.ColumnPanel,
    direction: 'vertical',
  },
  delay: dragDelayTime,
  chosenClass: 'wea-edc-dragging',
  dragoverBubble: false,
  forceFallback: true,
  swapThreshold: 0.65
};
const droppableOpts = {
  group: {
    name: 'columnpanel_child',
    pull: false,
    put: [DragKey.ComCard, DragKey.COM]
  }
};
const SortableItem = ({ com, index, uuid, renderItem, ...restProps }) => {
  if(!com) {
    return (
      <Droppable ecId={`${this && this.props && this.props.ecId || ''}_Droppable@6w02ym`}
        index={index}
        uuid={uuid}
        options={droppableOpts}
        {...restProps}
      />
    );
  }

  return (
    <div data-uuid={uuid} data-index={index} {...restProps}>
      {renderItem(com)}
    </div>
  );
};

export default class ColumnPanel2Design extends BaseDesign {
  containerRef = React.createRef();

  state = {
    dragIndex: -1,
    isOver: false
  };

  componentDidMount() {
    this.setContainerHeight();
  }

  componentDidUpdate() {
    this.setContainerHeight();
  }

  setContainerHeight() {
    const container = this.containerRef.current;

    if (!container) return;

    setTimeout(() => {
      const dom = container.node;

      if (!dom) return;

      dom.removeAttribute('style');
      dom.style.height = `${Math.max(dom.offsetHeight, MINH)}px`;
    }, 1500);
  }

  onDragEnd(e) {
    const { isOver } = this.state;
    let { newIndex, oldIndex } = e;
    
    newIndex = Math.floor(newIndex / 2);
    oldIndex = Math.floor(oldIndex / 2);

    this.setState({ dragIndex: -1, isOver: false });

    if (!isOver || newIndex === oldIndex) return;

    const { data: { coms }, onPropsChange } = this.props;
    const newComs = utils.sort(toJS(coms), { newIndex, oldIndex });

    onPropsChange('coms', newComs);
  }

  onDragMove(e) {
    const { isOver } = this.state;
    const newIsOver = e.to === this.containerRef.current.node;

    if (isOver !== newIsOver) {
      this.setState({ isOver: newIsOver });
    }
  }

  onDragStart(e) {
    this.setState({ dragIndex: e.oldIndex, isOver: true });
  }

  renderContent() {
    const { dragIndex, isOver } = this.state;
    const { data: { size, coms }, field, renderItem, onRemove } = this.props;
    const style = { width: `${1 / size * 100}%` };
    const dragKey = `${DragKey.ColumnPanel}_${field.uuid}`;
    const clsNameStr = classNames('wea-edc-columnpanel-row', {
      "can-droppable": !coms.filter(Boolean).length
    });
    const group = {
      ...sortableOpts.group,
      pull: true,
      put: [dragKey, DragKey.ComCard, DragKey.COM]
    };

    return (
      <Fragment ecId={`${this && this.props && this.props.ecId || ''}_Fragment@1rkzoe`}>
        <Sortable ecId={`${this && this.props && this.props.ecId || ''}_Sortable@553u8g`}
          ref={this.containerRef}
          onChange={() => { }}
          className={clsNameStr}
          options={{
            ...sortableOpts,
            group,
            handle: '.wea-edc-fb-com',
            onStart: this.onDragStart.bind(this),
            onEnd: this.onDragEnd.bind(this),
            onMove: this.onDragMove.bind(this)
          }}
        >
          {Array(size).fill(0).map((s, index) => (
            <Fragment ecId={`${this && this.props && this.props.ecId || ''}_Fragment@0y44up@${index}`}>
              <SortableItem ecId={`${this && this.props && this.props.ecId || ''}_SortableItem@daue8k@${index}`} 
                index={index}
                uuid={field.uuid}
                com={coms[index]}
                style={style}
                className={classNames({
                  first: 0 === index,
                  last: size === index + 1
                })}
                renderItem={renderItem}
              />
              <div className={classNames({ hide: index !== dragIndex || isOver })} style={style}></div>
            </Fragment>
          ))}
        </Sortable>
        <ActionGroup ecId={`${this && this.props && this.props.ecId || ''}_ActionGroup@ypesf5`} onDel={onRemove} />
      </Fragment>
    );
  }
}

ColumnPanel2Design.defaultProps = {
  ...BaseDesign.defaultProps,
  data: defaultData
};